/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ModelEditor.java
 *
 * Created on 02.04.2012, 10:53:33
 */
package Editoren;

import Schnittstellen.Graphisches.Modelle.JmeModell;
import Schnittstellen.Graphisches.Texturen.Textur;
import Schnittstellen.ObjectManager;
import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.io.File;
import java.util.concurrent.Callable;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 *
 * @author Geez
 */
public class ModelEditor extends javax.swing.JPanel {

    private JmeCanvasContext context;
    private Canvas canvas;
    private SimpleApplication modelapp;
    private Dimension canvasSize = new Dimension(480, 320);
    private Spatial spatial;
    private ObjectManager om = ObjectManager.getInstance();
    private JFrame chooserframe;
    private JFileChooser filechooser;
    private Vector3f scale;

    /** Creates new form ModelEditor */
    public ModelEditor() {
        initComponents();
        setupChooser();
        JMESetup();

    }

    private void JMESetup() {
        modelapp = new SimpleApplication() {

            private Box b;

            @Override
            public void simpleInitApp() {
                b = new Box(1, 1, 1);
                spatial = new Geometry("box", b);
                Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                m.setColor("Color", ColorRGBA.Blue);
                spatial.setMaterial(m);
                rootNode.attachChild(spatial);
            }

            /*   @Override
            public void simpleUpdate(float tpf) {
            super.simpleUpdate(tpf);
            if (spatial != null) {
            spatial.rotate(0, tpf, 0);
            }
            }*/
        };
        AppSettings settings = new AppSettings(true);
        settings.setWidth(canvasSize.width);
        settings.setHeight(canvasSize.height);


        modelapp.setPauseOnLostFocus(true);
        modelapp.setSettings(settings);
        modelapp.createCanvas();
        context = (JmeCanvasContext) modelapp.getContext();
        canvas = context.getCanvas();
        canvas.setSize(settings.getWidth(), settings.getHeight());
        canvasPanel.add(canvas);
        this.add(canvasPanel, BorderLayout.CENTER);


      //  modelapp.startCanvas();


        modelapp.enqueue(new Callable<Void>() {

            public Void call() {
                modelapp.getFlyByCamera().setDragToRotate(true);
                modelapp.getFlyByCamera().setMoveSpeed(10);
                return null;
            }
        });

    }

    private void setupChooser() {
        chooserframe = new JFrame("load..");
        filechooser = new JFileChooser();
        filechooser.setAcceptAllFileFilterUsed(false);
        filechooser.setMultiSelectionEnabled(true);
        filechooser.addChoosableFileFilter(new FileNameExtensionFilter("*.obj; *.xml", "obj", "xml"));
        chooserframe.add(filechooser);
        chooserframe.pack();
        chooserframe.setResizable(false);
        filechooser.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().matches(JFileChooser.APPROVE_SELECTION)) {
                    if (filechooser.getSelectedFiles().length > 1) {
                        for (File f : filechooser.getSelectedFiles()) {
                            importModel(f);
                        }
                    } else {
                        importModel(filechooser.getSelectedFile());
                    }
                }
                Lmodellist.updateUI();
                chooserframe.setVisible(false);
            }
        });
    }

    private void importModel(File selectedFile) {
        if (om.addToAssets(ObjectManager.Dateityp.MODELL, selectedFile)) {
            om.addModel(new JmeModell(selectedFile.getName()));
        }
    }

    private void loadModel(final JmeModell m) {
        modelapp.enqueue(new Callable<Void>() {

            public Void call() {
                modelapp.getRootNode().detachAllChildren();
                //m.setScale(new Vector3f(0.1f, 0.1f, 0.1f));
                spatial = m.getModel(modelapp.getAssetManager());
                modelapp.getRootNode().attachChild(spatial);

                DirectionalLight sun = new DirectionalLight();

                sun.setDirection(new Vector3f(0.1f, 0.7f, -1.0f));
                modelapp.getRootNode().addLight(sun);
                modelapp.update();
                return null;
            }
        });
    }

    private void deleteModel(JmeModell m) {
        modelapp.enqueue(new Callable<Void>() {

            public Void call() {
                modelapp.getRootNode().detachAllChildren();
                modelapp.update();
                return null;
            }
        });
        om.removeFromAssets(ObjectManager.Dateityp.MODELL, m);
    }

    private void scaleSpatial(final float x, final float y, final float z) {
        scale = new Vector3f(x, y, z);
        modelapp.enqueue(new Callable<Void>() {

            public Void call() {
                spatial.setLocalScale(x, y, z);
                modelapp.update();
                return null;
            }
        });
    }

    private void changeTexture(final Textur t) {
        modelapp.enqueue(new Callable<Void>() {

            public Void call() {
                Material m = new Material(modelapp.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");

                if (t == null) {
                    m.setColor("Color", ColorRGBA.randomColor());
                    spatial.setMaterial(m);
                } else {
                    m.setTexture("ColorMap", modelapp.getAssetManager().loadTexture("Textures/" + t.getEditorName()));
                    spatial.setMaterial(m);
                }
                modelapp.update();
                return null;
            }
        });
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        Lmodellist = new javax.swing.JList();
        Badd = new javax.swing.JButton();
        Bdel = new javax.swing.JButton();
        Bload = new javax.swing.JButton();
        canvasPanel = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        SscaleZ = new javax.swing.JSpinner();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        SscaleX = new javax.swing.JSpinner();
        SscaleY = new javax.swing.JSpinner();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        SrotZ = new javax.swing.JSpinner();
        SrotX = new javax.swing.JSpinner();
        SrotY = new javax.swing.JSpinner();
        jLabel7 = new javax.swing.JLabel();
        SrotW = new javax.swing.JSpinner();
        jButton1 = new javax.swing.JButton();
        CBtextur = new javax.swing.JComboBox();
        ChBtextur = new javax.swing.JCheckBox();

        setLayout(new java.awt.BorderLayout());

        jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        Lmodellist.setModel(new javax.swing.AbstractListModel() {
            public int getSize() { return om.getModellbank().size(); }
            public Object getElementAt(int i) { return om.getModellbank().get(i); }
        });
        Lmodellist.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        Lmodellist.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                LmodellistValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(Lmodellist);

        jPanel1.add(jScrollPane1, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 40, 130, 350));

        Badd.setText("+");
        Badd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                BaddActionPerformed(evt);
            }
        });
        jPanel1.add(Badd, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 10, -1, -1));

        Bdel.setText("-");
        Bdel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                BdelActionPerformed(evt);
            }
        });
        jPanel1.add(Bdel, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 10, -1, -1));

        Bload.setText("Reload");
        Bload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                BloadActionPerformed(evt);
            }
        });
        jPanel1.add(Bload, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 396, -1, -1));

        add(jPanel1, java.awt.BorderLayout.EAST);

        javax.swing.GroupLayout canvasPanelLayout = new javax.swing.GroupLayout(canvasPanel);
        canvasPanel.setLayout(canvasPanelLayout);
        canvasPanelLayout.setHorizontalGroup(
            canvasPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 735, Short.MAX_VALUE)
        );
        canvasPanelLayout.setVerticalGroup(
            canvasPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 430, Short.MAX_VALUE)
        );

        add(canvasPanel, java.awt.BorderLayout.CENTER);

        jPanel2.setName(""); // NOI18N
        jPanel2.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jLabel1.setText("Scale Z");
        jPanel2.add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 70, -1, -1));

        SscaleZ.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(1.0d), Double.valueOf(0.0d), null, 0.01));
        SscaleZ.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                SscaleZStateChanged(evt);
            }
        });
        jPanel2.add(SscaleZ, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 70, 78, -1));

        jLabel2.setText("Scale X");
        jPanel2.add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 10, -1, -1));

        jLabel3.setText("Scale Y");
        jPanel2.add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 40, -1, -1));

        SscaleX.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(1.0f), Double.valueOf(0.0f), null, 0.01f));
        SscaleX.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                SscaleXStateChanged(evt);
            }
        });
        jPanel2.add(SscaleX, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 10, 78, -1));

        SscaleY.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(1.0d), Double.valueOf(0.0d), null, 0.01));
        SscaleY.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                SscaleYStateChanged(evt);
            }
        });
        jPanel2.add(SscaleY, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 40, 78, -1));

        jLabel4.setText("RotateZ");
        jLabel4.setEnabled(false);
        jPanel2.add(jLabel4, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 10, -1, -1));

        jLabel5.setText("RotateX");
        jLabel5.setEnabled(false);
        jPanel2.add(jLabel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(170, 10, -1, -1));

        jLabel6.setText("RotateY");
        jLabel6.setEnabled(false);
        jPanel2.add(jLabel6, new org.netbeans.lib.awtextra.AbsoluteConstraints(170, 40, -1, -1));

        SrotZ.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(0.0d), null, null, 0.1));
        SrotZ.setEnabled(false);
        SrotZ.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                SrotZStateChanged(evt);
            }
        });
        jPanel2.add(SrotZ, new org.netbeans.lib.awtextra.AbsoluteConstraints(370, 10, 78, -1));

        SrotX.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(0.0d), null, null, 0.1));
        SrotX.setEnabled(false);
        jPanel2.add(SrotX, new org.netbeans.lib.awtextra.AbsoluteConstraints(220, 10, 78, -1));

        SrotY.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(0.0d), null, null, 0.1));
        SrotY.setEnabled(false);
        SrotY.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                SrotYStateChanged(evt);
            }
        });
        jPanel2.add(SrotY, new org.netbeans.lib.awtextra.AbsoluteConstraints(220, 40, 78, -1));

        jLabel7.setText("RotateW");
        jLabel7.setEnabled(false);
        jPanel2.add(jLabel7, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 40, -1, -1));

        SrotW.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(0.0d), null, null, 0.1));
        SrotW.setEnabled(false);
        SrotW.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                SrotWStateChanged(evt);
            }
        });
        jPanel2.add(SrotW, new org.netbeans.lib.awtextra.AbsoluteConstraints(370, 40, 78, -1));

        jButton1.setText("save");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jPanel2.add(jButton1, new org.netbeans.lib.awtextra.AbsoluteConstraints(800, 50, -1, -1));

        CBtextur.setModel(new javax.swing.DefaultComboBoxModel(om.getTexturbank()));

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, ChBtextur, org.jdesktop.beansbinding.ELProperty.create("${selected}"), CBtextur, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        CBtextur.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                CBtexturItemStateChanged(evt);
            }
        });
        jPanel2.add(CBtextur, new org.netbeans.lib.awtextra.AbsoluteConstraints(480, 40, 140, -1));

        ChBtextur.setText("Eigene Textur verwenden");
        ChBtextur.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ChBtexturActionPerformed(evt);
            }
        });
        jPanel2.add(ChBtextur, new org.netbeans.lib.awtextra.AbsoluteConstraints(480, 10, -1, -1));

        add(jPanel2, java.awt.BorderLayout.SOUTH);

        bindingGroup.bind();
    }// </editor-fold>//GEN-END:initComponents

private void SscaleXStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_SscaleXStateChanged
    scaleSpatial(Float.valueOf(SscaleX.getValue() + ""), Float.valueOf(SscaleY.getValue() + ""), Float.valueOf(SscaleZ.getValue() + ""));
}//GEN-LAST:event_SscaleXStateChanged

private void SscaleYStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_SscaleYStateChanged
    scaleSpatial(Float.valueOf(SscaleX.getValue() + ""), Float.valueOf(SscaleY.getValue() + ""), Float.valueOf(SscaleZ.getValue() + ""));
}//GEN-LAST:event_SscaleYStateChanged

private void SrotWStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_SrotWStateChanged
}//GEN-LAST:event_SrotWStateChanged

private void SscaleZStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_SscaleZStateChanged
    scaleSpatial(Float.valueOf(SscaleX.getValue() + ""), Float.valueOf(SscaleY.getValue() + ""), Float.valueOf(SscaleZ.getValue() + ""));
}//GEN-LAST:event_SscaleZStateChanged

private void SrotYStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_SrotYStateChanged
}//GEN-LAST:event_SrotYStateChanged

private void SrotZStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_SrotZStateChanged
}//GEN-LAST:event_SrotZStateChanged

private void BaddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BaddActionPerformed
    chooserframe.setVisible(true);
}//GEN-LAST:event_BaddActionPerformed

private void LmodellistValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_LmodellistValueChanged
    JmeModell m = (JmeModell) Lmodellist.getSelectedValue();
    loadModel(m);
}//GEN-LAST:event_LmodellistValueChanged

private void BloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BloadActionPerformed
    JmeModell m = (JmeModell) Lmodellist.getSelectedValue();
    loadModel(m);
}//GEN-LAST:event_BloadActionPerformed

private void BdelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BdelActionPerformed
    JmeModell m = (JmeModell) Lmodellist.getSelectedValue();
    deleteModel(m);
    Lmodellist.updateUI();

}//GEN-LAST:event_BdelActionPerformed

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
    JmeModell m = (JmeModell) Lmodellist.getSelectedValue();
    m.setScale(scale);
}//GEN-LAST:event_jButton1ActionPerformed

private void ChBtexturActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ChBtexturActionPerformed
    if (ChBtextur.isSelected()) {
        if (CBtextur.getSelectedItem() != null) {
            changeTexture((Textur) CBtextur.getSelectedItem());
        }
    } else {
        changeTexture(null);
    }

}//GEN-LAST:event_ChBtexturActionPerformed

private void CBtexturItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_CBtexturItemStateChanged
    if (evt.getStateChange() == ItemEvent.SELECTED) {
        if (ChBtextur.isSelected()) {
            if (CBtextur.getSelectedItem() != null) {
                changeTexture((Textur) CBtextur.getSelectedItem());
            }
        }
    }
}//GEN-LAST:event_CBtexturItemStateChanged
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton Badd;
    private javax.swing.JButton Bdel;
    private javax.swing.JButton Bload;
    private javax.swing.JComboBox CBtextur;
    private javax.swing.JCheckBox ChBtextur;
    private javax.swing.JList Lmodellist;
    private javax.swing.JSpinner SrotW;
    private javax.swing.JSpinner SrotX;
    private javax.swing.JSpinner SrotY;
    private javax.swing.JSpinner SrotZ;
    private javax.swing.JSpinner SscaleX;
    private javax.swing.JSpinner SscaleY;
    private javax.swing.JSpinner SscaleZ;
    private javax.swing.JPanel canvasPanel;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}
